/**
 * 系统健康检查工具
 * EndoSight-UC 医疗AI系统
 *
 * 提供全面的系统健康状态监控和深度检查
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import winston from 'winston';
import db from '../config/database.js';
import { generatePrometheusMetrics, getMetricsSummary } from './metrics.js';
import { withCircuitBreaker } from '../middleware/errorHandler.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 健康检查结果枚举
export const HealthStatus = {
  HEALTHY: 'healthy',
  DEGRADED: 'degraded',
  UNHEALTHY: 'unhealthy',
  CRITICAL: 'critical'
};

// 健康检查阈值配置
const HEALTH_THRESHOLDS = {
  // 内存使用阈值 (MB)
  memory: {
    warning: 512,
    critical: 1024
  },
  // CPU使用阈值 (百分比)
  cpu: {
    warning: 70,
    critical: 90
  },
  // 磁盘使用阈值 (百分比)
  disk: {
    warning: 80,
    critical: 95
  },
  // 响应时间阈值 (毫秒)
  responseTime: {
    warning: 1000,
    critical: 3000
  },
  // 错误率阈值 (百分比)
  errorRate: {
    warning: 5,
    critical: 15
  }
};

// 健康检查历史记录
const healthHistory = [];
const MAX_HISTORY_SIZE = 100;

/**
 * 执行深度系统健康检查
 * @param {Object} options - 检查选项
 * @returns {Promise<Object>} 健康检查结果
 */
export const performDeepHealthCheck = async (options = {}) => {
  const {
    includeDatabase = true,
    includeAI = true,
    includeFileSystem = true,
    includeMetrics = true,
    timeout = 30000
  } = options;

  const startTime = Date.now();
  const checkId = `health_check_${Date.now()}`;

  const result = {
    checkId,
    timestamp: new Date().toISOString(),
    status: HealthStatus.HEALTHY,
    overallScore: 100,
    duration: 0,
    components: {},
    summary: {
      healthy: 0,
      degraded: 0,
      unhealthy: 0,
      critical: 0
    },
    alerts: [],
    recommendations: []
  };

  try {
    logger.info(`开始深度健康检查: ${checkId}`);

    // 并行执行各项检查
    const checks = [];

    // 数据库健康检查
    if (includeDatabase) {
      checks.push(checkDatabaseHealth());
    }

    // 文件系统健康检查
    if (includeFileSystem) {
      checks.push(checkFileSystemHealth());
    }

    // AI服务健康检查
    if (includeAI) {
      checks.push(checkAIServiceHealth());
    }

    // 系统资源健康检查
    checks.push(checkSystemResourceHealth());

    // 应用程序健康检查
    checks.push(checkApplicationHealth());

    // 等待所有检查完成
    const checkResults = await Promise.allSettled(checks);

    // 处理检查结果
    for (const checkResult of checkResults) {
      if (checkResult.status === 'fulfilled') {
        const componentResult = checkResult.value;
        result.components[componentResult.name] = componentResult;

        // 更新状态统计
        result.summary[componentResult.status]++;

        // 生成告警
        if (componentResult.alerts && componentResult.alerts.length > 0) {
          result.alerts.push(...componentResult.alerts);
        }

        // 生成建议
        if (componentResult.recommendations && componentResult.recommendations.length > 0) {
          result.recommendations.push(...componentResult.recommendations);
        }

        // 更新整体状态
        if (componentResult.status === HealthStatus.CRITICAL) {
          result.status = HealthStatus.CRITICAL;
        } else if (componentResult.status === HealthStatus.UNHEALTHY && result.status !== HealthStatus.CRITICAL) {
          result.status = HealthStatus.UNHEALTHY;
        } else if (componentResult.status === HealthStatus.DEGRADED && result.status === HealthStatus.HEALTHY) {
          result.status = HealthStatus.DEGRADED;
        }
      } else {
        logger.error('健康检查执行失败:', checkResult.reason);
        result.summary.unhealthy++;
        result.status = result.status === HealthStatus.HEALTHY ? HealthStatus.UNHEALTHY : result.status;
      }
    }

    // 计算整体健康分数
    result.overallScore = calculateHealthScore(result.summary);

    // 添加指标信息
    if (includeMetrics) {
      result.metrics = {
        summary: getMetricsSummary(),
        prometheusOutput: generatePrometheusMetrics()
      };
    }

    result.duration = Date.now() - startTime;

    // 记录健康检查历史
    recordHealthCheck(result);

    logger.info(`健康检查完成: ${checkId}`, {
      status: result.status,
      score: result.overallScore,
      duration: result.duration,
      components: Object.keys(result.components).length
    });

    return result;

  } catch (error) {
    result.status = HealthStatus.CRITICAL;
    result.duration = Date.now() - startTime;
    result.alerts.push({
      severity: 'critical',
      message: '健康检查执行失败',
      details: error.message
    });

    logger.error(`健康检查失败: ${checkId}`, error);
    return result;
  }
};

/**
 * 数据库健康检查
 */
const checkDatabaseHealth = async () => {
  const componentName = 'database';
  const startTime = Date.now();

  try {
    // 使用熔断器保护数据库检查
    const dbHealth = await withCircuitBreaker('database-health', async () => {
      return await db.healthCheck();
    });

    const duration = Date.now() - startTime;

    if (dbHealth.status === 'healthy') {
      return {
        name: componentName,
        status: HealthStatus.HEALTHY,
        responseTime: duration,
        details: dbHealth,
        alerts: [],
        recommendations: []
      };
    } else {
      return {
        name: componentName,
        status: HealthStatus.UNHEALTHY,
        responseTime: duration,
        details: dbHealth,
        alerts: [{
          severity: 'warning',
          message: '数据库连接异常',
          details: dbHealth.error
        }],
        recommendations: ['检查数据库服务状态', '验证数据库连接配置']
      };
    }

  } catch (error) {
    return {
      name: componentName,
      status: HealthStatus.CRITICAL,
      responseTime: Date.now() - startTime,
      details: { error: error.message },
      alerts: [{
        severity: 'critical',
        message: '数据库健康检查失败',
        details: error.message
      }],
      recommendations: ['立即检查数据库服务', '验证数据库配置和网络连接']
    };
  }
};

/**
 * 文件系统健康检查
 */
const checkFileSystemHealth = async () => {
  const componentName = 'filesystem';
  const startTime = Date.now();

  try {
    const checks = [];

    // 检查上传目录
    const uploadPath = process.env.UPLOAD_PATH || './uploads/medical_images';
    try {
      const stats = fs.statSync(uploadPath);
      if (stats.isDirectory()) {
        const files = fs.readdirSync(uploadPath);
        const totalSize = files.reduce((sum, file) => {
          const filePath = path.join(uploadPath, file);
          const fileStats = fs.statSync(filePath);
          return sum + (fileStats.isFile() ? fileStats.size : 0);
        }, 0);

        checks.push({
          name: 'upload_directory',
          status: 'healthy',
          path: uploadPath,
          fileCount: files.length,
          totalSize: totalSize
        });
      } else {
        checks.push({
          name: 'upload_directory',
          status: 'error',
          path: uploadPath,
          message: '上传路径不是目录'
        });
      }
    } catch (error) {
      checks.push({
        name: 'upload_directory',
        status: 'error',
        path: uploadPath,
        error: error.message
      });
    }

    // 检查日志目录
    const logPath = './logs';
    try {
      if (!fs.existsSync(logPath)) {
        fs.mkdirSync(logPath, { recursive: true });
      }
      const stats = fs.statSync(logPath);
      checks.push({
        name: 'log_directory',
        status: 'healthy',
        path: logPath,
        exists: true
      });
    } catch (error) {
      checks.push({
        name: 'log_directory',
        status: 'error',
        path: logPath,
        error: error.message
      });
    }

    // 检查数据库目录
    const dbPath = './data';
    try {
      if (!fs.existsSync(dbPath)) {
        fs.mkdirSync(dbPath, { recursive: true });
      }
      const stats = fs.statSync(dbPath);
      checks.push({
        name: 'database_directory',
        status: 'healthy',
        path: dbPath,
        exists: true
      });
    } catch (error) {
      checks.push({
        name: 'database_directory',
        status: 'error',
        path: dbPath,
        error: error.message
      });
    }

    const hasErrors = checks.some(check => check.status === 'error');
    const alerts = [];
    const recommendations = [];

    if (hasErrors) {
      alerts.push({
        severity: 'warning',
        message: '文件系统检查发现问题',
        details: checks.filter(c => c.status === 'error').map(c => `${c.name}: ${c.error || c.message}`)
      });
      recommendations.push('检查文件系统权限', '确保必要的目录存在且可写');
    }

    return {
      name: componentName,
      status: hasErrors ? HealthStatus.UNHEALTHY : HealthStatus.HEALTHY,
      responseTime: Date.now() - startTime,
      details: { checks },
      alerts,
      recommendations
    };

  } catch (error) {
    return {
      name: componentName,
      status: HealthStatus.CRITICAL,
      responseTime: Date.now() - startTime,
      details: { error: error.message },
      alerts: [{
        severity: 'critical',
        message: '文件系统健康检查失败',
        details: error.message
      }],
      recommendations: ['检查文件系统权限', '验证磁盘空间']
    };
  }
};

/**
 * AI服务健康检查
 */
const checkAIServiceHealth = async () => {
  const componentName = 'ai_service';
  const startTime = Date.now();

  try {
    const aiServiceUrl = process.env.AI_INFERENCE_URL;
    if (!aiServiceUrl) {
      return {
        name: componentName,
        status: HealthStatus.DEGRADED,
        responseTime: Date.now() - startTime,
        details: { error: 'AI服务URL未配置' },
        alerts: [{
          severity: 'warning',
          message: 'AI推理服务未配置',
          details: 'AI_INFERENCE_URL环境变量未设置'
        }],
        recommendations: ['配置AI推理服务URL', '启动AI推理服务']
      };
    }

    // 使用熔断器保护AI服务检查
    const response = await withCircuitBreaker('ai-service-health', async () => {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 5000);

      try {
        const fetch = (await import('node-fetch')).default;
        const result = await fetch(`${aiServiceUrl}/health`, {
          signal: controller.signal,
          timeout: 5000
        });
        clearTimeout(timeoutId);
        return result;
      } catch (error) {
        clearTimeout(timeoutId);
        throw error;
      }
    });

    const duration = Date.now() - startTime;

    if (response && response.ok) {
      const data = await response.json();
      return {
        name: componentName,
        status: HealthStatus.HEALTHY,
        responseTime: duration,
        details: {
          url: aiServiceUrl,
          serviceStatus: data.status || 'unknown',
          response: data
        },
        alerts: [],
        recommendations: []
      };
    } else {
      return {
        name: componentName,
        status: HealthStatus.UNHEALTHY,
        responseTime: duration,
        details: {
          url: aiServiceUrl,
          statusCode: response?.status,
          statusText: response?.statusText
        },
        alerts: [{
          severity: 'warning',
          message: 'AI服务响应异常',
          details: `HTTP ${response?.status}: ${response?.statusText}`
        }],
        recommendations: ['检查AI服务状态', '验证AI服务连接']
      };
    }

  } catch (error) {
    return {
      name: componentName,
      status: HealthStatus.CRITICAL,
      responseTime: Date.now() - startTime,
      details: { error: error.message },
      alerts: [{
        severity: 'critical',
        message: 'AI服务健康检查失败',
        details: error.message
      }],
      recommendations: ['启动AI推理服务', '检查网络连接']
    };
  }
};

/**
 * 系统资源健康检查
 */
const checkSystemResourceHealth = () => {
  const componentName = 'system_resources';
  const startTime = Date.now();

  try {
    const memUsage = process.memoryUsage();
    const uptime = process.uptime();

    const checks = {
      memory: {
        rss: memUsage.rss,
        heapUsed: memUsage.heapUsed,
        heapTotal: memUsage.heapTotal,
        external: memUsage.external,
        heapUsagePercent: (memUsage.heapUsed / memUsage.heapTotal) * 100
      },
      uptime: uptime,
      activeHandles: process._getActiveHandles().length,
      activeRequests: process._getActiveRequests().length
    };

    // 评估内存使用情况
    const memoryMB = memUsage.rss / 1024 / 1024;
    let memoryStatus = 'healthy';
    const alerts = [];
    const recommendations = [];

    if (memoryMB > HEALTH_THRESHOLDS.memory.critical) {
      memoryStatus = 'critical';
      alerts.push({
        severity: 'critical',
        message: '内存使用过高',
        details: `当前使用: ${memoryMB.toFixed(2)}MB`
      });
      recommendations.push('立即优化内存使用', '检查内存泄漏');
    } else if (memoryMB > HEALTH_THRESHOLDS.memory.warning) {
      memoryStatus = 'warning';
      alerts.push({
        severity: 'warning',
        message: '内存使用偏高',
        details: `当前使用: ${memoryMB.toFixed(2)}MB`
      });
      recommendations.push('监控内存使用趋势');
    }

    // 评估堆内存使用
    if (checks.memory.heapUsagePercent > 90) {
      alerts.push({
        severity: 'warning',
        message: '堆内存使用率过高',
        details: `堆内存使用率: ${checks.memory.heapUsagePercent.toFixed(2)}%`
      });
    }

    // 评估运行时间
    if (uptime < 60) {
      alerts.push({
        severity: 'info',
        message: '服务刚启动',
        details: `运行时间: ${uptime.toFixed(0)}秒`
      });
    }

    const overallStatus = memoryStatus === 'critical' ? HealthStatus.CRITICAL :
                         memoryStatus === 'warning' ? HealthStatus.DEGRADED :
                         HealthStatus.HEALTHY;

    return {
      name: componentName,
      status: overallStatus,
      responseTime: Date.now() - startTime,
      details: checks,
      alerts,
      recommendations
    };

  } catch (error) {
    return {
      name: componentName,
      status: HealthStatus.CRITICAL,
      responseTime: Date.now() - startTime,
      details: { error: error.message },
      alerts: [{
        severity: 'critical',
        message: '系统资源检查失败',
        details: error.message
      }],
      recommendations: ['检查系统监控工具']
    };
  }
};

/**
 * 应用程序健康检查
 */
const checkApplicationHealth = () => {
  const componentName = 'application';
  const startTime = Date.now();

  try {
    const checks = {
      nodeVersion: process.version,
      platform: process.platform,
      arch: process.arch,
      pid: process.pid,
      environment: process.env.NODE_ENV || 'development',
      port: process.env.PORT || 4000
    };

    // 检查环境配置
    const requiredEnvVars = ['JWT_SECRET', 'UPLOAD_PATH'];
    const missingEnvVars = requiredEnvVars.filter(envVar => !process.env[envVar]);

    const alerts = [];
    const recommendations = [];

    if (missingEnvVars.length > 0) {
      alerts.push({
        severity: 'warning',
        message: '缺少必需的环境变量',
        details: missingEnvVars.join(', ')
      });
      recommendations.push('配置所有必需的环境变量');
    }

    // 检查Node.js版本
    const nodeVersion = parseInt(process.version.slice(1).split('.')[0]);
    if (nodeVersion < 18) {
      alerts.push({
        severity: 'warning',
        message: 'Node.js版本较低',
        details: `当前版本: ${process.version}, 建议使用Node.js 18+`
      });
      recommendations.push('升级到Node.js 18或更高版本');
    }

    return {
      name: componentName,
      status: alerts.some(a => a.severity === 'critical') ? HealthStatus.CRITICAL :
             alerts.some(a => a.severity === 'warning') ? HealthStatus.DEGRADED :
             HealthStatus.HEALTHY,
      responseTime: Date.now() - startTime,
      details: checks,
      alerts,
      recommendations
    };

  } catch (error) {
    return {
      name: componentName,
      status: HealthStatus.CRITICAL,
      responseTime: Date.now() - startTime,
      details: { error: error.message },
      alerts: [{
        severity: 'critical',
        message: '应用程序健康检查失败',
        details: error.message
      }],
      recommendations: ['检查应用程序配置']
    };
  }
};

/**
 * 计算整体健康分数
 */
const calculateHealthScore = (summary) => {
  const total = summary.healthy + summary.degraded + summary.unhealthy + summary.critical;
  if (total === 0) return 100;

  const weights = {
    healthy: 100,
    degraded: 70,
    unhealthy: 30,
    critical: 0
  };

  const weightedSum = (summary.healthy * weights.healthy +
                      summary.degraded * weights.degraded +
                      summary.unhealthy * weights.unhealthy +
                      summary.critical * weights.critical);

  return Math.round(weightedSum / total);
};

/**
 * 记录健康检查历史
 */
const recordHealthCheck = (result) => {
  healthHistory.unshift({
    timestamp: result.timestamp,
    status: result.status,
    score: result.overallScore,
    duration: result.duration,
    componentCount: Object.keys(result.components).length
  });

  // 保持历史记录在合理大小
  if (healthHistory.length > MAX_HISTORY_SIZE) {
    healthHistory.pop();
  }
};

/**
 * 获取健康检查历史
 */
export const getHealthHistory = (limit = 50) => {
  return healthHistory.slice(0, limit);
};

/**
 * 获取健康趋势
 */
export const getHealthTrend = (hours = 24) => {
  const cutoffTime = Date.now() - (hours * 60 * 60 * 1000);
  return healthHistory.filter(check =>
    new Date(check.timestamp).getTime() > cutoffTime
  );
};

// 配置日志记录器
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.simple()
    })
  ]
});

export default {
  performDeepHealthCheck,
  checkDatabaseHealth,
  checkFileSystemHealth,
  checkAIServiceHealth,
  checkSystemResourceHealth,
  checkApplicationHealth,
  getHealthHistory,
  getHealthTrend,
  HealthStatus,
  HEALTH_THRESHOLDS
};